package com.cbj.netty.handler;

import com.cbj.netty.util.RPCUtil;
import com.cbj.netty.protocol.Content;
import com.cbj.netty.protocol.Header;
import com.cbj.netty.protocol.PackageMsg;
import com.cbj.netty.rpc.Dispatcher;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ServerRequestHandler extends ChannelInboundHandlerAdapter {
    Dispatcher dispatcher;
    public ServerRequestHandler(Dispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        PackageMsg requestPackage = (PackageMsg) msg;
        // 返回必须要有requestId，确保返回到对应的客户端
        // 把任务交给其他的eventloop执行，把业务的任务打散
        // 将IO任务和业务任务分离开。
        ctx.executor().parent().next().execute(new Runnable() {
            @Override
            public void run() {
                Content myContent = requestPackage.getContent();
                // 服务名
                String name = myContent.getName();
                // 方法名，方法类型和参数
                String methodName = myContent.getMethodName();
                Class<?>[] parameterTypes = myContent.getParameterTypes();
                Object[] args = myContent.getArgs();
                // 从注册中心拿到对应的实现类
                Object o = dispatcher.get(name);
                Class<?> aClass = o.getClass();
                Object res = null;
                try {
                    Method method = aClass.getMethod(methodName, parameterTypes);
                    res = method.invoke(o, args);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }catch (IllegalAccessException e){
                    e.printStackTrace();
                }catch (InvocationTargetException e){
                    e.printStackTrace();
                }
                Content content = new Content();
                content.setRes((String)res);
                byte[] contentMsg = RPCUtil.getBytes(content);
                Header header = new Header(0x12121213, requestPackage.getHeader().getRequestId(),contentMsg.length);
                byte[] headerMsg = RPCUtil.getBytes(header);
                ByteBuf byteBuf = RPCUtil.comHeadAndContent(headerMsg, contentMsg);
                ctx.writeAndFlush(byteBuf);
            }
        });
    }
}